home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-06-08 | 62.2 KB | 1,809 lines |
- TURBO DEBUGGER FOR WINDOWS
- Assembler-level debugging
-
- This file contains information about Assembler-level debugging. The
- contents of the file are as follows:
-
- 1. When source debugging isn't enough
- 2. The CPU window
- 3. The Code Pane
- 4. The Register and Flags panes
- 5. The Selector pane
- 6. The Data pane
- 7. The Stack pane
- 8. The assembler
- 9. The Dump window
- 10. The Registers window
- 11. Assembler-specific bugs
- 12. Inline assembler tips
- 13. Inline assembler keywords
-
- The material in this file is for programmers who are familiar with
- programming the 80x86 processor family in assembler. You don't need
- to use the information in this chapter to debug your programs, but
- there are certain problems that might be easier to find using
- techniques discussed in this chapter.
-
- We explain when you might want to use assembler-level debugging and
- describe the CPU window with its built-in disassembler and
- assembler. You then learn how to examine and modify raw hex data
- bytes, how to peruse the function calling stack, how to examine and
- modify the CPU registers, and finally how to examine and modify the
- CPU flags.
-
-
-
- ===================================================================
- 1. When source debugging isn't enough
- ===================================================================
-
- When you're debugging a program, most of the time you refer to data
- and code at the source level; you refer to symbol names exactly as
- you typed them in your source code, and you proceed through your
- program by executing pieces of source code.
-
- Sometimes, however, you can gain insight into a problem by looking
- at the exact instructions that the compiler generated, the contents
- of the CPU registers, and the contents of the stack. To do this,
- you need to be familiar with both the 80x86 family of processors
- and with how the compiler turns your source code into machine
- instructions. Because many excellent books are available about the
- internal workings of the CPU, we won't go into that in detail here.
- You can quickly learn how the compiler turns your source code into
- machine instructions by looking at the instructions generated for
- each line of source code.
-
- C++ lets you write lines of source code that perform many actions
- at once, and TDW lets you step one source line at a time, not one
- expression at a time. However, you sometimes want to know the
- result of executing a small piece of one source line. By stepping
- through your program one machine instruction at a time, you can
- examine intermediate results, although it does require some effort
- to figure out how the compiler translated your source statements
- into machine code.
-
-
-
- ===================================================================
- 2. The CPU window
- ===================================================================
-
- The CPU window shows you the entire state of the CPU. You can
- examine
-
- o examine and change the bits and bytes that make up your program's
- code and data
-
- o access the contents of any area of memory referenced by a
- selector
-
- o use the built-in assembler in the Code pane to patch your program
- temporarily by entering instructions exactly as you would type
- assembler source statements
-
- o access the underlying bytes of any data structure, display them
- in a number of formats, and change them
-
- Open a CPU window by choosing View|CPU from the menu bar. Depending
- on what you're viewing in the current window, the new CPU window
- comes up positioned at the appropriate code, data, or stack
- location, thus providing a convenient method for taking a "low-
- level" look at the code, data, or stack location your cursor is
- currently on.
-
- The following table shows where your cursor will be positioned when
- you choose the CPU command:
-
-
- ___________________________________________________________________
-
- Current window CPU pane Position
- ___________________________________________________________________
-
- Stack window Stack Current SS:SP
- Module window Code Current CS:IP
- Variable window Data/Code Address of item
- Watches window Data/Code Address of item
- Inspector window Data/Code Address of item
- Breakpoint Code Breakpoint address
- (if not global)
- ____________________________________________________________________
-
-
- The CPU window has six panes. To go from one pane to the next,
- press Tab or Shift-Tab, or click the pane with your mouse. The line
- at the top of the CPU window shows what processor type you have
- (8086, 80286, 80386, or 80486).
-
- o The top left pane (Code pane) shows the disassembled program code
- intermixed with the source lines.
-
- o The second top pane (Register pane) shows the contents of the CPU
- registers.
-
- o The top right pane (Flags pane) shows the state of the eight CPU
- flags.
-
- o The middle left pane (Selector pane--below the Code pane) shows
- all Windows selectors and indicates the general contents of each.
-
- o The bottom left pane (Data pane--below the Selector pane) shows a
- raw hex dump of any area of memory you choose.
-
- o The bottom right pane (Stack pane) shows the contents of the
- stack.
-
- In the Code pane, an arrow shows the current program location
- (CS:IP). In the Stack pane, an arrow shows the current stack
- pointer (SS:SP).
-
- If the highlighted instruction in the Code pane references a memory
- location, the memory address and its current contents are displayed
- on the top line of the CPU window. This lets you see both where an
- instruction operand points in memory and the value that is about to
- be read or written over.
-
- As with all windows and panes, pressing Alt-F10 pops up the pane's
- local menu. If control-key shortcuts are enabled, pressing the Ctrl
- key with the highlighted letter of the desired local menu command
- executes the command.
-
- In the Code, Data, and Stack panes, you can press Ctrl-LeftArrow
- and Ctrl-RightArrow to shift the starting display address of the
- pane by 1 byte up or down. Pressing these keys is easier than using
- the Goto command if you just want to adjust the display slightly.
-
-
-
- ===================================================================
- 3. The Code pane
- ===================================================================
-
- This pane shows the disassembled instructions at an address that
- you choose. An arrow shows the current program location (CS:IP).
-
- There are two ways of choosing an address:
-
- o Use the local menu Goto, Origin, Follow, Caller, or Previous
- command.
-
- o Position on a code selector in the Selector pane, then choose
- Examine to display the contents of the selector in the Code pane.
-
- The left part of each disassembled line shows the address of the
- instruction. The address is displayed either as a hex segment and
- offset, or with the segment value replaced with the CS register
- name if the segment value is the same as the current CS register.
- If the window is wide enough (zoomed or resized), the bytes that
- make up the instruction are displayed. The disassembled instruction
- appears to the right.
-
- If the highlighted instruction in the Code pane references a memory
- location, the memory address and its current contents are displayed
- on the top line of the CPU window. This feature lets you see both
- where an instruction operand points in memory and the value that is
- about to be read or written over.
-
-
- The disassembler
- ================
-
- The Code pane automatically disassembles and displays your program
- instructions. If an address corresponds to either a global symbol,
- static symbol, or a line number, the line before the disassembled
- instruction displays the symbol if the Mixed display mode is set to
- Yes. Also, if there is a line of source code that corresponds to
- the symbol address, it is displayed after the symbol.
-
- Global symbols appear simply as the symbol name. Static symbols
- appear as the module name, followed by a cross hatch (#) for C or
- Assembler or a period (.) for Pascal, followed by the static symbol
- name. Line numbers appear as the module name, followed by a cross
- hatch (#) for C or Assembler or a period (.) for Pascal, followed
- by the decimal line number.
-
- When an immediate operand is displayed, you can infer its size from
- the number of digits: A byte immediate has 2 digits, and a word
- immediate has 4 digits.
-
- TDW can detect an 8087, 80287, 80387, or 80486 numeric coprocessor
- and disassemble those instructions if a floating-point chip or
- emulator is present.
-
- The instruction mnemonic RETF indicates that this is a far return
- instruction. The normal RET mnemonic indicates a near return.
-
- Where possible, the target of JMP and CALL instructions is
- displayed symbolically. If CS:IP is a JMP or conditional jump
- instruction, an up-arrow or down-arrow that shows jump direction
- will be displayed only if the executing instruction will cause the
- jump to occur. Also, memory addresses used by MOV, ADD, and other
- instructions display symbolic addresses.
-
-
- The Code pane local menu
- ========================
-
- If you don't come up in the Code pane, use Tab or Shift-Tab to get
- there. Then press Alt-F10 to bring up the local menu.
- ________________
- | Goto... |
- | Origin |
- | Follow |
- | Caller |
- | Previous |
- | Search... |
- | View source |
- | Mixed Yes |
- |________________|
- | New cs:ip |
- | Assemble... |
- | I/O |
- |________________|
-
- Goto
- ----
-
- After choosing this command, you're prompted for the new address to
- go to. You can enter addresses that are outside of your program, to
- examine code in the BIOS ROM, inside DOS, and in Windows programs.
- See Chapter 9 in the debugger manual for complete information on
- entering addresses.
-
- The Previous command restores the Code pane to the position it had
- before the Goto command was issued.
-
-
- Origin
- ------
-
- Positions you at the current program location as indicated by the
- CS:IP register pair. This command is useful when you want to return
- to where you started.
-
- The Previous command restores the Code pane to the position it had
- before the Origin command was issued.
-
-
- Follow
- ------
-
- Positions you at the destination address of the currently high-
- lighted instruction. The Code pane is repositioned to display the
- code at the address where the currently highlighted instruction
- will transfer control. For conditional jumps, the address is shown
- as if the jump occurred.
-
- This command can be used with the CALL, JMP, conditional jump (JZ,
- JNE, LOOP, JCXZ, and so forth) and INT instructions.
-
- The Previous command restores the Code pane to the position it had
- before the Follow command was selected.
-
-
- Caller
- ------
-
- Positions you at the instruction that called the current interrupt
- or subroutine.
-
- This command won't always work. If the interrupt routine or
- subroutine has pushed data items onto the stack, sometimes TDW
- can't figure out where the routine was called from.
-
- The Previous command restores the Code pane to the position it had
- before the Caller command was selected.
-
-
- Previous
- --------
-
- Restores the Code pane position to the address before the last
- command that explicitly changed the display address. Using the
- arrow keys and PgUp and PgDn does not cause the position to be
- remembered.
-
- When you choose Previous, the Code pane position is remembered, so
- that repeated use of the Previous command causes the Code pane to
- switch back and forth between two addresses.
-
-
- Search
- ------
-
- Lets you enter an instruction or byte list to search for. Enter an
- instruction exactly as you would with the Assemble command.
-
- Be careful which instructions you try to search for; you should
- only search for instructions that don't change the bytes they
- assemble to, depending on their location in memory. For example,
- searching for the following instructions is no problem:
-
- PUSH DX
- POP [DI+4]
- ADD AX,100
-
- but searching for the following instructions can cause unpre-
- dictable results:
-
- JE 123
- CALL MYFUNC
- LOOP 100
-
- You can also enter a byte list instead of an instruction. See
- Chapter 9 in the debugger manual for more on entering byte lists.
-
-
- View Source
- -----------
-
- This command opens a Module window to show you the source code that
- corresponds to the current disassembled instruction. If there is no
- corresponding source code (for example, you're in Windows code, or
- there's no debugging information), you just stay in the Code pane.
-
-
- Mixed
- -----
-
- Toggles between the three ways of displaying disassembled instruc-
- tions and source code:
-
- No No source code is displayed, only disassembled instructions.
-
- Yes Source code lines appear before the first disassembled
- instruction for that source line. The pane is set to this
- display mode if your current module is a high-level language
- source module.
-
- Both Source code lines replace disassembled lines for those lines
- that have corresponding source code; otherwise, the disassem-
- bled instruction appears. Use this mode when you are debugging
- an assembler module, and you want to see the original source
- code, instead of the corresponding disassembled instruction.
- The pane is set to this display mode if your current module is
- an assembler source module.
-
- New CS:IP
- ---------
-
- Sets the program location counter (CS:IP registers) to the current-
- ly highlighted address. When you rerun your program, execution
- starts at this address. This is useful when you want to skip over a
- piece of code without executing it.
-
- Use this command with extreme care. If you adjust the CS:IP to a
- location where the stack is in a different state than at the
- current CS:IP, your program will almost certainly crash. Do not use
- this command to set the CS:IP to an address outside the current
- routine.
-
-
- Assemble
- --------
-
- Assembles an instruction, replacing the one at the currently
- highlighted location. You are prompted for the instruction to
- assemble. See the section "The assembler" later in this file for
- more details.
-
- You can also invoke this command by simply starting to type the
- statement you want to assemble. When you do this, a dialog box
- appears exactly as if you had specified Assemble.
-
-
- I/O
- ---
-
- Reads or writes a value in the CPU's I/O space and lets you examine
- the contents of I/O registers on cards and write to them.
-
- It pops up this menu:
- _____________
- | In byte... |
- | Out byte... |
- | Read word... |
- | Write word... |
- |_____________|
-
- In Byte
- -------
-
- Reads a byte from an I/O port. You are prompted for the I/O port
- whose value you want to examine. Use the Read Word option to read
- from a word-sized I/O port.
-
- Out Byte
- --------
-
- Writes a byte to an I/O port. You are prompted for the I/O port to
- write to and the value you want to write. Use the Write Word option
- to write to a word-sized I/O port.
-
- Read Word
- ---------
-
- Reads a word from an I/O port. You are prompted for the I/O port
- whose value you want to examine. Use the In Byte option to read
- from a byte-sized I/O port.
-
- Write Word
- ----------
-
- Writes a word to an I/O port. You are prompted for the I/O port to
- write to and the value you want to write. Use the Out Byte option
- to write to a byte-sized I/O port.
-
- IN and OUT instructions access the I/O space where peripheral
- device controllers (such as serial cards, disk controllers, and
- video adapters) reside.
-
- Be careful when you use these commands. Some I/O devices consider
- reading their ports to be a significant event that causes the
- device to perform some action, such as resetting status bits or
- loading a new data byte into the port. You may disrupt the normal
- operation of the program you are debugging or the device with
- indiscriminate use of these commands.
-
-
-
- ===================================================================
- 4. The Register and Flags panes
- ===================================================================
-
- The Register pane, which is the top pane to the right of the Code
- pane, shows the contents of the CPU registers.
-
- The top right pane is the Flags pane, which shows the state of the
- eight CPU flags. The following table lists the different flags and
- how they are shown in the Flags pane:
-
- ________________________________________________
-
- Letter in pane Flag name___
-
- c Carry
- z Zero
- s Sign
- o Overflow
- p Parity
- a Auxiliary carry
- i Interrupt enable
- d Direction___
- ________________________________________________
-
- The Register pane local menu
- ============================
-
- Press Alt-F10 to pop up the Register pane local menu. Or, if
- control-key shortcuts are enabled, use the Ctrl key with the first
- letter of the desired command to access the command.
- _______________________
- | Increment |
- | Decrement |
- | Zero |
- | Change... |
- | Registers 32-bit No |
- |_______________________|
-
- Increment
- ---------
-
- Adds 1 to the value in the currently highlighted register. This is
- an easy way to make small adjustments in the value of a register to
- compensate for "off-by-one" bugs.
-
-
- Decrement
- ---------
-
- Subtracts 1 from the value in the currently highlighted register.
-
-
- Zero
- ----
-
- Sets the value of the currently highlighted register to 0.
-
- Change
- ------
-
- Changes the value of the currently highlighted register. You are
- prompted for the new value. You can make full use of the expression
- evaluator to enter a new value.
-
- You can also invoke this command by simply starting to type the new
- value for the register. A dialog box appears exactly as if you had
- specified Change.
-
-
- Registers 32-bit
- ----------------
-
- On an Intel 80X86 32-bit processor (80386 or later), toggles
- between displaying the CPU registers as 16-bit or 32-bit values.
- You usually see 16-bit registers, unless you use this command to
- set the display to 32-bit registers. You really need to see 32-bit
- registers only if you're debugging a program that uses the 32-bit
- addressing an arithmetic capabilities of the 386 chip. If you are
- debugging a program that uses only 16-bit addressing and
- arithmetic, use the 16-bit register display.
-
-
- The Flags pane local menu
- =========================
- ________
- | Toggle |
- |________|
-
- Press Alt-F10 to pop up the Flags pane local menu or, if control-
- key shortcuts are enabled, use the Ctrl key with the first letter
- of the desired command to access the command.
-
-
- Toggle
- ------
-
- Sets the value of the flag to 0 if it was 1, and to 1 if it was 0.
- The value 0 corresponds to "clear," and 1 indicates "set." You can
- also press Enter or Spacebar to toggle the value of the currently
- highlighted flag.
-
-
-
- ===================================================================
- 5. The Selector pane
- ===================================================================
-
- This pane shows a list of protected-mode selectors and indicates
- some information about each one.
-
- A selector can be either valid or invalid. If valid, the selector
- points to a location in the protected-mode descriptor table
- corresponding to a memory address. If invalid, the selector is
- unused.
-
- For a valid selector, the pane shows the following:
-
- o if the contents are data or code
-
- o if the selector is loaded (present in memory) or unloaded
- (swapped out to disk)
-
- o the length of the referenced memory area in bytes
-
- o the access mode of the memory area (blank; Read/Write, Up;
- others????)
-
- If the selector references a data segment, there's additional
- information on the access rights (Read/Write or Read only) and the
- direction the segment expands in memory (Up or Down).
-
-
- The Selector pane local menu
- ============================
-
- At the Selector pane, press Alt-F10 to pop up the local menu or, if
- control-key shortcuts are enabled, use the Ctrl key with the
- highlighted letter of the desired command to access the command.
-
- You can use the local menu of the Selector pane to go to a new
- selector (the Selector command) or see the contents of the selector
- currently highlighted in the Selector pane (the Examine command).
- The contents display in either the Code pane or the Data pane,
- depending on their nature.
- ____________
- | Selector |
- | Examine... |
- |____________|
-
- Selector
- --------
-
- Prompts you to type a selector to display in the pane. You can use
- full expression syntax to enter the selector. If you enter a
- numeric value, TDW assumes it is decimal unless you use the syntax
- of the current language to indicate that the value is hexadecimal.
-
- For example, if the current language were C, you could type the
- hexadecimal selector value 7F as 0x7F. For Pascal, you'd type it as
- $7F. You could also type the decimal value 127 in order to go to
- selector 7F.
-
- Another method of entering the selector value is to display the CPU
- window and check the segment register values. If a register holds
- the selector you're interested in, you can enter the name of the
- register preceded by an underscore (_). For example, you could type
- the data segment register as _DS.
-
-
- Examine
- -------
-
- Displays the contents of the memory area referenced by the current
- selector and switches focus to the pane where the contents are
- displayed. If the selector points to a code segment, the contents
- are diplayed in the Code pane. If the contents are data, they're
- displayed in the Data pane.
-
-
-
- ===================================================================
- 6. The Data pane
- ===================================================================
-
- This pane shows a raw display of an area of memory you've selected.
- The leftmost part of each line shows the address of the data
- displayed in that line. The address is displayed either as a hex
- segment and offset, or with the segment value replaced with one of
- the register names if the segment value is the same as that
- register. The Data pane matches registers in the following order:
- DS, ES, SS, CS.
-
- Next, the raw display of one or more data items is displayed. The
- format of this area depends on the display format selected with the
- Display As local menu command. If you choose one of the floating-
- point display formats (Comp, Float, Real, Double, Extended), a
- single floating-point number is displayed on each line. Byte format
- displays 8 bytes per line, Word format displays 4 words per line,
- and Long format displays 2 long words per line.
-
- When the data is displayed as bytes, the rightmost part of each
- line shows the display characters that correspond to the data bytes
- displayed. TDW displays all byte values as their display
- equivalents, so don't be surprised if you see graphics characters
- displayed to the right of the hex dump area--these are just the
- display equivalents of the hex byte values.
-
- If you use the Data pane to examine the contents of the display
- memory, the ROM BIOS data area, or the vectors in low memory, you
- will see the values that are there when the program being debugged
- runs, not the actual values in memory when TDW is running. These
- are not the same values that are in these memory areas at the time
- you look at them. TDW detects when you're accessing areas of memory
- that it uses as well, and it gets the correct data value from where
- it stores the user program's copy of these data areas.
-
- There are two ways of choosing an address:
-
- o Use the local menu Goto, Follow, or Previous command.
-
- o Position on a data selector in the Selector pane, then choose
- Examine to display the contents of the selector in the Data pane.
-
-
- The Data pane local menu
- ========================
-
- Once you are positioned in the Data pane, press Alt-F10 to pop up
- the local menu or, if control-key shortcuts are enabled, use the
- Ctrl key with the first letter of the desired command to access it.
- ______________
- | Goto... |
- | Search... |
- | Next |
- | Change... |
- | Follow |
- | Previous |
- |______________|
- | Display as |
- | Block |
- |______________|
-
- The Data pane local menu lets you go to a new address, search for a
- character string, change bytes at the current cursor location,
- follow near or far pointer chains, restore a previous address,
- change how data appears in the window, and move, change, read, and
- write blocks of memory.
-
-
- Goto
- ----
-
- Positions you at an address in your data. Enter the new address you
- want to go to. You can enter addresses inside DOS, in resident
- utilities, or outside your program, which lets you examine data in
- the BIOS data area. See Chapter 9 in the debugger manual for a
- complete discussion of how to enter addresses.
-
-
- Search
- ------
-
- Searches for a character string, starting at the current memory
- address as indicated by the cursor position. Enter the byte list to
- search for. The search does not wrap around from the end of the
- segment to the beginning. See Chapter 9 in the debugger manual for
- a complete discussion of byte lists.
-
- Next
- ----
-
- Searches for the next instance of the byte list you previously
- specified with the Search command.
-
-
- Change
- ------
-
- Lets you change the bytes at the current cursor location. If you're
- over an ASCII display or the format is Byte, you're prompted for a
- byte list. Otherwise, you're prompted for an item of the current
- display type. See Chapter 9 in the debugger manual for a discussion
- of byte lists.
-
- You can also invoke this command by simply starting to type the new
- value or values. This brings up a dialog box exactly as if you had
- chosen the Change command.
-
-
- Follow
- ------
-
- Opens a menu that lets you follow near or far pointer chains.
- ________________________
- | Near code |
- | Far code |
- |________________________|
- | Offset to data |
- | Segment:offset to data |
- | Base segment:0 to data |
- |________________________|
-
- Near Code
- ---------
-
- This command interprets the word under the cursor in the Data pane
- as an offset into the current code segment as specified by the CS
- register. The Code pane becomes the current pane and is positioned
- to this address.
-
- Far Code
- --------
-
- This command interprets the doubleword under the cursor in the Data
- pane as a far address (segment and offset). The Code pane becomes
- the current pane and is positioned to this address.
-
- Offset to Data
- --------------
-
- This command lets you follow word (near, offset only) pointer
- chains. The Data pane is set to the offset specified by the word in
- memory at the current cursor location.
-
- Segment:Offset to Data
- ----------------------
-
- This command lets you follow long (far, segment, and offset)
- pointer chains. The Data pane is set to the offset specified by the
- two words in memory at the current cursor location.
-
- Base Segment:0 to Data
- ----------------------
-
- This command interprets the word under the cursor as a segment
- address and positions the Data pane to the start of that segment.
-
-
- Previous
- --------
-
- Restores the Data pane address to the address before the last
- command that explicitly changed the display address. Using the
- arrow keys and PgUp and PgDn does not cause the position to be
- remembered.
-
- TDW maintains a stack of the last five addresses, so you can
- backtrack through multiple uses of the Follow menu or Goto
- commands.
-
-
- Display As
- ----------
-
- Lets you choose how data appears in the Data pane. You can choose
- from any data format used by C++ and assembler. The menu options
- are
- __________
- | Byte |
- | Word |
- | Long |
- | Comp |
- | Float |
- | Real |
- | Double |
- | Extended |
- |__________|
-
- Byte
- ----
-
- Sets the Data pane to display as hexadecimal bytes. This
- corresponds to the C++ Byte type.
-
- Word
- ----
-
- Sets the Data pane to display as word hexadecimal numbers. The 2-
- byte hexadecimal value is shown. This corresponds to the C int data
- type and the C++ Word type.
-
- Long
- ----
-
- Sets the Data pane to display as long hexadecimal integers. The 4-
- byte hex value is shown. This corresponds to the C++ longint type.
-
- Comp
- ----
-
- Sets the Data pane to display 8-byte integers. The decimal value of
- the integer is shown. This is the C++ Comp (IEEE) data type.
-
- Float
- -----
-
- Sets the Data pane to display as short floating-point numbers. The
- scientific notation floating-point value is shown. This is the same
- as the C++ Single (IEEE) type.
-
- Real
- ----
-
- Sets the Data pane to display C++'s 6-byte floating-point numbers.
- The scientific notation floating-point value is shown. This is the
- C++ Real type.
-
- Double
- ------
-
- Sets the data pane to display 8-byte floating-point numbers. The
- scientific notation floating-point value is shown. This is the same
- as the C++ Double type.
-
- Extended
- --------
-
- Sets the Data pane to display 10-byte floating-point numbers. The
- scientific notation floating-point value is shown. This is the
- internal format used by the 80x87 coprocessor. It also corresponds
- to the C++ Extended (IEEE) type, and the assembler TBYTE type.
-
-
- Block
- -----
-
- Lets you manipulate blocks of memory. You can move, clear and set
- memory blocks, and read and write memory blocks to and from disk
- files. Block brings up the following menu:
- _________
- | Clear...|
- | Move... |
- | Set... |
- | Read... |
- | Write... |
- |_________|
-
- Clear
- -----
-
- Sets a contiguous block of memory to zero (0). You are prompted for
- the address and the number of bytes to clear.
-
- Move
- ----
-
- Copies a block of memory from one address to another. You are
- prompted for the source address, the destination address, and how
- many bytes to copy.
-
- Set
- ---
-
- Sets a contiguous block of memory to a specific byte value. You are
- prompted for the address of the block, how many bytes to set, and
- the value to set them to.
-
- Read
- ----
-
- Reads all or a portion of a file into a block of memory. You are
- prompted first for the file name to read from, then for the address
- to read it into, and finally for how many bytes to read.
-
- Write
- -----
-
- Writes a block of memory to a file. You are prompted first for the
- file name to write to, then for the address of the block to write
- and how many bytes to write.
-
-
- ===================================================================
- 7. The Stack pane
- ===================================================================
-
- The Stack pane, in the lower right corner of the CPU window, shows
- the contents of the stack. An arrow shows the current stack pointer
- (SS:IP).
-
-
- The Stack pane local menu
- =========================
-
- At the Stack pane, press Alt-F10 to pop up the local menu or, if
- control-key shortcuts are enabled, use the Ctrl key with the first
- letter of the desired command to access the command.
- ___________
- | Goto... |
- | Origin |
- | Follow |
- | Previous |
- | Change... |
- |___________|
-
- Goto
- ----
-
- Positions you at an address in the stack. Enter the new stack
- address. If you want, you can enter addresses outside your pro-
- gram's stack, although you would usually use the Data pane to
- examine arbitrary data outside your program. See Chapter 9 in the
- debugger manual for information about how to enter addresses.
-
- The Previous command restores the Stack pane to the position it had
- before the Goto command was issued.
-
-
- Origin
- ------
-
- Positions you at the current stack location as indicated by the
- SS:SP register pair. This command is useful when you want to return
- to where you started.
-
- The Previous command restores the Stack pane to the position it had
- before the Origin command was issued.
-
-
- Follow
- ------
-
- Positions you at the word in the stack pointed to by the currently
- highlighted word. This is useful for following stack-frame threads
- back to a calling procedure.
-
- The Previous command restores the Stack pane to the position it had
- before the Follow command was issued.
-
-
- Previous
- --------
-
- Restores the Stack pane position to the address before the last
- command that explicitly changed the display address. Using the
- arrow keys and PgUp and PgDn does not cause the position to be
- remembered.
-
- Repeated use of the Previous command causes the Stack pane to
- switch back and forth between two addresses.
-
-
- Change
- ------
-
- Lets you enter a new word value for the currently highlighted stack
- word.
-
- You can also invoke this command by simply starting to type the new
- value for the highlighted stack item. A dialog box appears, exactly
- as if you had specified the Change command.
-
-
-
- ===================================================================
- 8. The assembler
- ===================================================================
-
- If you use the Assemble command in the Code pane local menu, TDW
- lets you assemble instructions for the 8086, 80186, 80286, 80386,
- and 80486 processors, and also for the 8087, 80287, and 80387
- numeric coprocessors.
-
- When you use TDW's built-in assembler to modify your program, the
- changes you make are not permanent. If you reload your program Run|
- Program Reset, or if you load another program using File|Open,
- you'll lose any changes you've made.
-
- Normally you use the assembler to test an idea for fixing your pro-
- gram. Once you've verified that the change works, you must change
- your source code and recompile and link your program.
-
- The following sections describe the differences between the built-
- in assembler and the syntax accepted by Turbo C++'s inline
- assembler.
-
-
- Operand address size overrides
- ==============================
-
- For the call (CALL), jump (JMP), and conditional jump (JNE, JL, and
- so forth) instructions, the assembler automatically generates the
- smallest instruction that can reach the destination address. You
- can use the NEAR and FAR overrides before the destination address
- to assemble the instruction with a specific size. For example,
-
- CALL FAR XYZ
- JMP NEAR A1
-
-
- Memory and immediate operands
- -----------------------------
-
- When you use a symbol from your program as an instruction operand,
- you must tell the built-in assembler whether you mean the contents
- of the symbol or the address of the symbol. If you use just the
- symbol name, the assembler treats it as an address, exactly as if
- you had used the assembler OFFSET operator before it. If you put
- the symbol inside brackets ([ ]), it becomes a memory reference.
- For example, if your program contains the data definition
-
- A DW 4
-
- then [A] references the area of memory where A is stored.
-
- When you assemble an instruction or evaluate an assembler
- expression to refer to the contents of a variable, use the name of
- the variable alone or between brackets:
-
- mov dx,a
- mov ax,[a]
-
- To refer to the address of the variable, use the OFFSET operator:
-
- mov ax,offset a
-
-
- Operand data size overrides
- ===========================
-
- For some instructions, you must specify the operand size using one
- of the following expressions before the operand:
-
- BYTE PTR
- WORD PTR
-
- Here are examples of instructions using these overrides:
-
- add BYTE PTR[si],10
- mov WORD PTR[bp+10],99
-
- In addition to these size overrides, you can use the following
- overrides to assemble 8087/80287/80387/80486 numeric processor
- instructions:
-
- DWORD PTR
- QWORD PTR
- TBYTE PTR
-
- Here are some examples using these overrides:
-
- fild QWORD PTR[bx]
- stp TBYTE PTR[bp+4]
-
-
- String instructions
- ===================
-
- When you assemble a string instruction, you must include the size
- (byte or word) as part of the instruction mnemonic. The assembler
- does not accept the form of the string instructions that uses a
- sizeless mnemonic with an operand that specifies the size. For
- example, use STOSW rather than STOS WORD PTR[di].
-
-
-
- ===================================================================
- 9. The Dump window
- ===================================================================
-
- The Dump window shows you a raw data dump of any area of memory. It
- works much like the Data pane in the CPU window, except that, when
- zoomed to full size, the Dump Window show twice as much data on a
- single line.
-
- See "The Data pane local menu" section earlier in this file for a
- description of the contents and local menu for this window.
-
- Typically, you'd use this window when you're debugging an assembler
- program at the source level, and you want to take a low-level look
- at some data areas. Use View|Dump to open a Dump window or View|
- Another|Dump to open multiple views on memory areas.
-
- You can also use this window if you're in an Inspector window, and
- you want to look at the raw bytes that make up the object you are
- inspecting. Use View|Dump to get a Dump window that's positioned to
- the data in the Inspector window.
-
-
- ===================================================================
- 10. The Registers window
- ===================================================================
-
- The Registers window shows you the contents of the CPU registers
- and flags. It works like a combination of the Registers and Flags
- panes in the CPU window. You can shrink the size of your Module
- window and put up a Registers window alongside it.
-
-
- See "The Register pane local menu" and "The Flags pane local menu"
- sections earlier in this file for a description of the contents and
- local menus for this window.
-
- Use this window when you're debugging an assembler program at the
- source level and want to look at the register values.
-
-
-
- =========================================
- 11. Assembler-specific bugs
- =========================================
-
- This section, which covers some of the common pitfalls of assembly
- language programming, is intended for people who have Turbo Assembler
- or use inline assembler in C++ programs. You should refer to the
- Turbo Assembler User's Guide for a fuller explanation on these
- oft-encountered errors--and tips on how to avoid them.
-
- Forgetting to return to DOS
- ===========================
-
- In C++, a program ends automatically when there is no more code to
- execute, even if no explicit termination command was written into the
- program. Not so in assembly language, where only those actions that
- you explicitly request are performed. When you run a program that has
- no command to return to DOS, execution simply continues right past the
- end of the program's code and into whatever code happens to be in the
- adjacent memory.
-
-
- Forgetting a RET instruction
- ============================
-
- The proper invocation of a subroutine consists of a call to the subroutine
- from another section of code, execution of the subroutine, and a return
- from the subroutine to the calling code. Remember to insert a RET
- instruction in each subroutine, so that the RETurn to the calling code
- occurs. When you're typing a program, it's easy to skip a RET and end
- up with an error.
-
-
- Generating the wrong type of return
- ===================================
- The PROC directive has two effects. First, it defines a name by which a
- procedure can be called. Second, it controls whether the procedure is a near
- or far procedure.
-
- The RET instructions in a procedure should match the type of the procedure,
- shouldn't they?
-
- Yes and no. The problem is that it's possible and often desirable to group
- several subroutines in the same procedure. Since these subroutines lack an
- associated PROC directive, their RET instructions take on the type of the
- overall procedure, which is not necessarily the correct type for the
- individual subroutines.
-
-
- Reversing operands
- ==================
-
- To many people, the order of instruction operands in 8086 assembly language
- seems backward (and there is certainly some justification for this
- viewpoint). If the line
-
- mov ax,bx
-
- meant "move AX to BX," the line would scan smoothly from left to right, and
- this is exactly the way in which many microprocessor manufacturers have
- designed their assembly languages.
-
- However, Intel took a different approach with 8086 assembly language; for
- us, the line means "move BX to AX," and that can sometimes cause confusion.
-
-
- Forgetting the stack or reserving a too-small stack
- ===================================================
-
- In most cases, you're treading on thin ice if you don't explicitly allocate
- space for a stack. Programs without an allocated stack sometimes run, but
- there is no assurance that these programs will run under all circumstances.
- DOS programs can have a .STACK directive to reserve space for the stack.
- In Turbo C++ for Windows, you can set the stack size by choosing
- Options|Compiler. For each program, you should reserve more than enough
- space for the deepest stack the program can use.
-
-
- Calling a subroutine that wipes out registers
- =============================================
-
- When you're writing assembler code, it's easy to think of the registers
- as local variables, dedicated to the use of the procedure you're working
- on at the moment. In particular, there's a tendency to assume that
- registers are unchanged by calls to other procedures. It just isn't
- so--the registers are global variables, and each procedure can preserve or
- destroy any or all registers.
-
-
- Using the wrong sense for a conditional jump
- ============================================
- The profusion of conditional jumps in assembly language (JE, JNE, JC,
- JNC, JA, JB, JG, and so on) allows tremendous flexibility in writing
- code--and also makes it easy to select the wrong jump for a given purpose.
- Moreover, since condition-handling in assembly language requires at least
- two separate lines, one for the comparison and one for the conditional
- jump (it requires many more lines for complex conditions), assembly
- language condition-handling is less intuitive and more prone to errors than
- condition-handling in C++.
-
-
- Forgetting about REP string overrun
- ===================================
-
- String instructions have a curious property: After they're executed, the
- pointers they use wind up pointing to an address 1 byte away (or 2 bytes
- for a word instruction) from the last address processed. This can cause
- some confusion with repeated string instructions, especially REP SCAS and
- REP CMPS.
-
-
- Relying on a zero CX to cover a whole segment
- =============================================
-
- Any repeated string instruction executed with CX equal to zero does nothing.
- Period. This can be convenient in that there's no need to check for the zero
- case before executing a repeated string instruction; on the other hand,
- there's no way to access every byte in a segment with a byte-sized string
- instruction.
-
-
- Using incorrect direction flag settings
- =======================================
-
- When a string instruction is executed, its associated pointer or pointers--
- SI or DI or both--increment or decrement. It all depends on the state of the
- direction flag.
-
- The direction flag can be cleared with CLD to cause string instructions to
- increment (count up) and can be set with STD to cause string instructions to
- decrement (count down). Once cleared or set, the direction flag stays in the
- same state until either another CLD or STD is executed, or until the flags
- are popped from the stack with POPF or IRET. While it's handy to be able to
- program the direction flag once and then execute a series of string
- instructions that all operate in the same direction, the direction flag can
- also be responsible for intermittent and hard-to-find bugs by causing the
- behavior of string instructions to depend on code that executed much earlier.
-
-
- Using the wrong sense for a repeated string comparison
- ======================================================
-
- The CMPS instruction compares two areas of memory; the SCAS instruction
- compares the accumulator to an area of memory. Prefixed by REPE, either
- of these instructions can perform a comparison until either CX becomes
- zero or a not-equal comparison occurs. Unfortunately, it's easy to become
- confused about which of the REP prefixes does what.
-
-
- Forgetting about string segment defaults
- ========================================
-
- Each of the string instructions defaults to using a source segment (if any)
- of DS, and a destination segment (if any) of ES. It's easy to forget this
- and try to perform, say, a STOSB to the data segment, since that's where
- all the data you're processing with non-string instructions normally resides.
-
-
- Converting incorrectly from byte to word operations
- ===================================================
- In general, it's desirable to use the largest possible data size (usually
- word, but dword on an 80386) for a string instruction, since string
- instructions with larger data sizes often run faster.
-
- There are a couple of potential pitfalls here. First, the conversion from a
- byte count to a word count by a simple
-
- shr cx,1
-
- loses a byte if CX is odd, since the least-significant bit is shifted out.
-
- Second, make sure you remember SHR divides the byte count by two. Using,
- say, STOSW with a byte rather than a word count can wipe out other data
- and cause problems of all sorts.
-
-
- Using multiple prefixes
- =======================
-
- String instructions with multiple prefixes are error-prone and should
- generally be avoided.
-
-
- Relying on the operand(s) to a string instruction
- =================================================
-
- The optional operand or operands to a string instruction are used for data
- sizing and segment overrides only, and do not guarantee that the memory
- location referenced is accessed.
-
-
- Wiping out a register with multiplication
- =========================================
-
- Multiplication--whether 8 bit by 8 bit, 16 bit by 16 bit, or 32 bit by 32
- bit--always destroys the contents of at least one register other than the
- portion of the accumulator used as a source operand.
-
-
- Forgetting that string instructions alter several registers
- ===========================================================
-
- The string instructions, MOVS, STOS, LODS, CMPS, and SCAS, can affect several
- of the flags and as many as three registers during execution of a single
- instruction. When you use string instructions, remember that SI, DI, or
- both either increment or decrement (depending on the state of the direction
- flag) on each execution of a string instruction. CX is also decremented at
- least once, and possibly as far as zero, each time a string instruction with
- a REP prefix is used.
-
-
- Expecting certain instructions to alter the carry flag
- ======================================================
-
- While some instructions affect registers or flags unexpectedly, other
- instructions don't even affect all the flags you might expect them to.
-
-
- Waiting too long to use flags
- =============================
-
- Flags last only until the next instruction that alters them, which is
- usually not very long. It's a good practice to act on flags as soon as
- possible after they're set, thereby avoiding all sorts of potential bugs.
-
-
- Confusing memory and immediate operands
- =======================================
-
- An assembler program may refer either to the offset of a memory variable or
- to the value stored in that memory variable. Unfortunately, assembly language
- is neither strict nor intuitive about the ways in which these two types of
- references can be made, and as a result, offset and value references to a
- memory variable are often confused.
-
-
- Failing to preserve everything in an interrupt handler
- ======================================================
-
- Every interrupt handler should explicitly preserve the contents of all
- registers. While it is valid to preserve explicitly only those registers
- that the handler modifies, it's good insurance just to push all registers
- on entry to an interrupt handler and pop all registers on exit.
-
-
- Forgetting group overrides in operands and data tables
- ======================================================
-
- Segment groups let you partition data logically into a number of areas
- without having to load a segment register every time you want to switch
- from one of those logical data areas to another.
-
-
-
- =========================================
- 12. Inline assembler tips
- =========================================
-
-
- Looking at raw hex data
- =======================
-
- You can use the Data|Add Watch and Data| Evaluate/Modify commands with
- a format modifier to look at raw data dumps. For example, if your
- language is Assembler,
-
- [ES:DI],20m
-
- specifies that you want to look at a raw hex memory dump of the 20 bytes
- pointed to by the ES:DI register pair.
-
-
- Source-level debugging
- ======================
-
- You can step through your assembler code using a Module window just as
- with any of the high-level languages. If you want to see the register
- values, you can put a Registers window to the right of the Module window.
-
- Sometimes, you may want to use a CPU window and see your source code as
- well. To do this, open a CPU window and choose the Code pane's Mixed
- command until it reads Both. That way you can see both your source code
- and machine code bytes. Remember to zoom the CPU window (by pressing F5)
- if you want to see the machine code bytes.
-
-
- Examining and changing registers
- ================================
-
- The obvious way to change registers is to highlight a register in either
- a CPU window or Registers window. A quick way to change a register is to
- choose Data|Evaluate/Modify. You can enter an assignment expression that
- directly modifies a register's contents. For example,
-
- SI = 99
-
- loads the SI register with 99.
-
- Likewise, you can examine registers using the same technique. For example,
-
- Alt-D E AX
-
- shows you the value of the AX register.
-
-
-
- =========================================
- 13. Inline assembler keywords
- =========================================
-
- This section lists the instruction mnemonics and other special symbols that
- you use when entering instructions with the inline assembler. The keywords
- presented here are the same as those used by Turbo Assembler.
-
-
- 8086/80186/80286 instructional mnemonics
- _________________________________________
- AAA INC LIDT** REPNZ
- AAD INSB* LLDT** REPZ
- AAM INSW* LMSW** RET
- AAS INT LOCK REFT
- ADC INTO LODSB ROL
- ADD IRET LODSW ROR
- AND JB LOOP SAHF
- ARPL** JBE LOOPNZ SAR
- BOUND* JCXZ LOOPZ SBB
- CALL JE LSL** SCASB
- CLC JL LTR** SCASW
- CLD JLE MOV SGDT**
- CLI JMP MOVSB SHL
- CLTS** JNB MOVSW SHR
- CMC JNBE MUL SLDT**
- CMP JNE NEG SMSW**
- CMPSB JNLE NOP STC
- CMPSW JNO NOT STD
- CWD JNP OR STI
- DAA JO OUT STOSB
- DAS JP OUTSB STOSW
- DEC JS OUTSW STR**
- DIV LAHF POP SUB
- ENTER* LAR** POPA* TEST
- ESC LDS POPF WAIT
- HLT LEA PUSH VERR**
- IDIV LEAVE PUSHA* VERW**
- IMUL LES PUSHF XCHG
- IN LGDT** RCL XLAT
- XOR
- ___________________________________________
-
- * Available only when running on the 186 and 286 processor
- ** Available only when running on the 286 processor
-
-
- TDW supports all 80386 and 80387 instruction mnemonics and registers:
-
-
- 80386 instruction mnemonics
- _________________________________________
-
- BSF LSS SETG SETS
- BSR MOVSX SETL SHLD
- BT MOVZX SETLE SHRD
- BTC POPAD SETNB CMPSD
- BTR POPFD SETNE STOSD
- BTS PUSHAD SETNL LODSD
- CDQ PUSHFD SETNO MOVSD
- CWDE SETA SETNP SCASD
- IRETD SETB SETNS INSD
- LFS SETBE SETO OUTSD
- LGS SETE SETP JECXZ
- __________________________________________
-
- 80486 instruction mnemonics
- _________________________________________
-
- BSWAP INVLPG
- CMPXCHG WBINVD
- INVD XADD
- _________________________________________
-
- 80386 registers
- _________________________________________
-
- EAX EDI
- EBX EBP
- ECX ESP
- EDX FS
- ESI GS
- _________________________________________
-
- CPU registers
- __________________________________________________________________
-
- Byte registers AH, AL, BH, BL, CH, CL, DH, DL
-
- Word registers AX, BX, CX, DX, SI, DI, SP, BP, FLAGS
-
- Segment registers CS, DS, ES, SS
-
- Floating registers ST, ST(0), ST(1), ST(2), ST(3), ST(4),
- ST(5), ST(6), ST(7)
- ___________________________________________________________________
-
- Special keywords
- _________________________________________
-
- WORD PTR TBYTE PTR
- BYTE PTR NEAR
- DWORD PTR FAR
- QWORD PTR SHORT
- _________________________________________
-
- 8087/80287 numeric coprocessor instruction mnemonics
- ____________________________________________________
- FABS FIADD FLDL2E FST
- FADD FIACOM FLDL2T FSTCW
- FADDP FIACOMP FLDPI FSTENV
- FBLD FIDIV FLDZ FSTP
- FBSTP FIDIVR FLD1 FSTSW**
- FCHS FILD FMUL FSUB
- FCLEX FIMUL FMULP FSUBP
- FCOM FINCSTP FNOP FSUBR
- FCOMP FINIT FNSTS** FSUBRP
- FCOMPP FIST FPATAN FTST
- FDECSTP FISTP FPREM FWAIT
- FDISI FISUB FPTAN FXAM
- FDIV FISUBR FRNDINT FXCH
- FDIVP FLD FRSTOR FXTRACT
- FDIVR FLDCWR FSAVENT FYL2X
- FDIVRP FLDENV FSCALE FYL2XPI
- FENI FLDLG2 FSETPM* F2XM1
- FFREE FLDLN2 FSQRT
- _____________________________________________________
-
- * Available only when running on the 287 numeric coprocessor.
- ** On the 80287, the fstsw instruction can use the AX register as an operand,
- as well as the normal memory operand.
-
-
- 80387 instruction mnemonics
- _________________________________________
-
- FCOS FUCOM
- FSIN FUCOMP
- FPREM1 FUCOMPP
- FSINCOS
- _________________________________________
-
- The 80x87 coprocessor chip and emulator
- =======================================
-
- This section is for programmers who are familiar with the operation
- if the 80x87 math coprocessor. If your program uses floating-point
- numbers, TDW lets you examine and change the state of the numeric
- coprocessor or, if the coprocessor is emulated, examine the state of the
- software emulator. (Windows permits you only to examine the state of the
- emulator, not to change it.) You don't need to use the capabilities
- described in this chapter to debug programs that use floating-point numbers,
- although some very subtle bugs may be easier to find.
-
- In this section, we discuss the differences between the 80x87 chip and
- the software emulator. We also describe the Numeric Processor window and
- show you how to examine and modify the floating-point registers, the status
- bits, and the control bits.
-
-
- The 80x87 chip vs. the emulator
- ===============================
-
- TDW automatically detects whether your program is using the math chip or the
- emulator and adjusts its behavior accordingly.
-
- Note that most programs use either the emulator or the math chip, not both
- within the same program. If you have written special assembler code that
- uses both, TDW won't be able to show you the status of the math chip; it
- reports on the emulator only.
-
-
- The Numeric Processor window
- ============================
-
- You create a Numeric Processor window by choosing the View|Numeric Processor
- command from the menu bar. The line at the top of the window shows the
- current instruction pointer, opcode, and data pointer. The instruction
- pointer is both shown as a 20-bit physical address. The data pointer is
- either a 16-bit or a 20-bit address, depending on the memory model. You
- can convert 20-bit addresses to segment and offset form by using the first
- four digits as the segment value and the last digit as the offset value.
-
- For example, if the top line shows IPTR=5A669, you can treat this as the
- address 5a66:9 if you want to examine the current data and instruction in
- a CPU window. This window has three panes: The left pane (Register pane)
- shows the contents of the floating-point registers, the middle pane
- (Control pane) shows the control flags, and the right pane (Status pane)
- shows the status flags.
-
-
- The top line shows you the following information about the last floating-
- point operation that was executed:
-
- o Emulator indicates that the numeric processor is being emulated. If there
- were a numeric processor, 8087, 80287, 80387, or 80486 would appear instead.
-
- o The IPTR shows the 20-bit physical address from which the last floating-
- point instruction was fetched.
-
- o The OPCODE shows the instruction type that was fetched.
-
- o The OPTR shows the 16-bit or 20-bit physical address of the memory address
- that the instruction referenced, if any.
-
-
- The Register pane
- -----------------
-
- The 80-bit floating-point registers
- -----------------------------------
-
- The Register pane shows each of the floating-point registers, ST(0) to
- ST(7), along with its status (valid/zero/special/empty). The contents
- are shown as an 80-bit floating-point number.
-
- If you've zoomed the Numeric Processor window (by pressing F5) or made
- it wider by using Window|Size/Move, you'll also see the floating-point
- registers displayed as raw hex bytes.
-
-
- The Register pane local menu
- ----------------------------
- ___________
- | Zero |
- | Empty |
- | Change... |
- |___________|
-
- To bring up the Register pane local menu, press Alt-F10, or use the Ctrl
- key with the first letter of the desired command to directly access the
- command.
-
- Zero
- ----
-
- Sets the value of the currently highlighted register to zero.
-
- Empty
- -----
-
- Sets the value of the currently highlighted register to empty. This is a
- special status that indicates that the register no longer contains valid
- data.
-
- Change
- ------
-
- Loads a new value into the currently highlighted register. You are
- prompted for the value to load. You can enter an integer or floating-
- point value, using the current language's expression parser. The value
- you enter is automatically converted to the 80-bit temporary real format
- used by the numeric coprocessor.
-
- You can also invoke this command by simply starting to type the new value
- for the floating-point register. A dialog box appears, exactly as if you
- had specified the Change command.
-
-
- The Control pane
- ----------------
-
- The control bits
- ----------------
-
- The following table lists the different control flags and how they appear
- in the Control pane:
- _________________________________________
-
- Name in pane Flag description__
-
- im Invalid operation mask
- dm Denormalized operand mask
- zm Zero divide mask
- om Overflow mask
- um Underflow mask
- pm Precision mask
- iem Interrupt enable mask (8087 only)
- pc Precision control
- rc Rounding control
- ic Infinity control__
-
-
- The Control pane local menu
- ---------------------------
- ________
- | Toggle |
- |________|
-
- Press Tab to go to the Control pane, then press Alt-F10 to pop up the
- local menu. (Alternatively, you can use the Ctrl key with the first letter
- of the desired command to access it.)
-
- Toggle
- ------
-
- Cycles through the values that the currently highlighted control flag
- can be set to. Most flags can only be set or cleared (0 or 1), so this
- command just toggles the flag to the other value. Some other flags have
- more than two values; for those flags, this command increments the flag
- value until the maximum value is reached, and then sets it back to zero.
-
- You can also toggle the control flag values by highlighting them and
- pressing Enter.
-
-
- The Status pane
- ---------------
-
-
- The status bits
- ---------------
-
- The following table lists the different status flags and how they appear
- in the Status pane:
- ____________________________________
-
- Name in pane Flag description__
-
- ie Invalid operation
- de Denormalized operand
- ze Zero divide
- oe Overflow
- ue Underflow
- pe Precision
- ir Interrupt request
- cc Condition code
- st Stack top pointer_
-
-
- The Status pane local menu
- --------------------------
- ________
- | Toggle |
- |________|
-
- Press Tab to move to the Statuspane, then press Alt-F10 to pop up the
- local menu. (You can also use the Ctrl key with the first letter of the
- desired command to access the command directly.)
-
-
- Toggle
- ------
-
- Cycles through the values that the currently highlighted status flag
- can be set to. Most flags can only be set or cleared (0 or 1), so this
- command just toggles the flag to the other value. Some other flags have
- more than two values; for those flags, this command increments the
- flag value until the maximum value is reached, and then sets it back to
- zero.
-
- You can also toggle the status flag values by highlighting them and
- pressing Enter.
-
-